<?php

namespace app\api\model;


use app\common\LogService;
use app\common\Notification;
use app\common\ScoreLog;
use Exception;
use think\facade\Db;
use think\Model;

class Fake extends Model
{
    // 卡密类型常量
    const TYPE_VIP = 1;
    const TYPE_EXP = 2;
    const TYPE_COINS = 3;
    const TYPE_INVITE_CODE = 4;

    public function getUseTimeAttr($value)
    {
        return date('Y-m-d H:i:s', $value);
    }
    public function getTypeAttr($value)
    {
        if ($value == 1) {
            return "VIP时长";
        } else if ($value == 2) {
            return "经验";
        } else if ($value == 3) {
            return "金币";
        }
    }
    public function useFake($fake,  $specialType = false)
    {
        $uid = getUid();
        $recordLog = function ($status, $message = '') use ($fake) {
            LogService::record(
                name: '卡密兑换',
                user_id: getUid(),
                target_id: $fake,
                status: $status,
                content: $message == '' ? [] : ['reason' => $message],
            );
        };
        $user = User::where('id', $uid)->lock(true)->find();


        // 启动事务
        Db::startTrans();
        try {
            // 查询并锁定卡密记录
            $card = self::where('fake', $fake)
                ->lock(true)
                ->find();
            // 验证卡密是否存在和可用
            if (!$card) {
                $recordLog(0, '');
                throw new Exception('卡密不存在');
            }
            if ($specialType && $card->getData('type') !=  $specialType) {
                throw new Exception('卡密无效');
            }
            if ($card->status == 1) {
                $recordLog(0, '卡密已被使用');
                throw new Exception('卡密已被使用');
            }
            // 根据卡密类型更新用户数据
            switch ($card->getData('type')) {
                case self::TYPE_VIP:
                    // VIP时长叠加
                    $newExpireTime = max(
                        time(),
                        $user->vip_expire_time ?: time()
                    ) + $card->value * 3600 * 24;
                    $user->vip_expire_time = $newExpireTime;
                    $msg = '卡密兑换成功,会员时长将于' . date('Y-m-d H:i:s', $newExpireTime) . '到期';
                    $icon = 3;
                    break;

                case self::TYPE_EXP:
                    // 增加经验值
                    $exp = $card->value;
                    $user->exp += $exp;
                    $msg = "卡密兑换成功,获得经验 [ {$exp} ]";
                    $icon = 3;
                    break;

                case self::TYPE_COINS:
                    // 增加金币
                    $score = $card->value;
                    $user->score += $score;
                    $msg = "卡密兑换成功,获得积分 [ {$score} ]";
                    $icon = 3;
                    ScoreLog::add($uid, $score, 'fake_use', '卡密使用');
                    break;
                case self::TYPE_INVITE_CODE:
                    break;
                default:
                    $recordLog(0, '无效的卡密类型');
                    throw new Exception('无效的卡密类型');
            }


            // 更新卡密状态
            $card->status = 1;
            $card->use_time = time();
            $card->use_user_id = $uid;
            $card->save();
            // 提交事务
            Db::commit();
            $recordLog(1);
            if ($uid != 0) {
                // 更新用户数据
                $user->save();
                Notification::send($uid, $msg, $icon, "/pages/fake/fake");
            }
            return true;
        } catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            $recordLog(0, $e->getMessage());
            throw new Exception($e->getMessage());
        }
    }
}
